using System.Text.Json;
using System.Text.Json.Serialization;
using MQTTnet;
using MQTTnet.Protocol;
using PHMEE.Diagnosis;
using PHMEE.VibrationDataGenerator.Data;
using Quartz;

namespace PHMEE.VibrationDataGenerator.Services;

public class VibDataGenerateDynamicTaskJob : IJob
{
    private readonly ILogger<VibDataGenerateDynamicTaskJob> _logger;
    private readonly MqttClientPool _mqttClientPool;

    public Guid JobId { get; set; } = Guid.NewGuid();

    public VibDataGenerateDynamicTaskJob(ILogger<VibDataGenerateDynamicTaskJob> logger, 
        MqttClientPool mqttClientPool)
    {
        _logger = logger;
        _mqttClientPool = mqttClientPool;
    }

    public async Task Execute(IJobExecutionContext context)
    {
        var dateTimeUtc = DateTime.UtcNow;
        // 获取任务的配置信息
        var taskConfig = context.MergedJobDataMap.Get("TaskConfig") as TaskConfig;

        // 获取 Channel Config
        var channelConfig = context.MergedJobDataMap.Get("ChannelConfig") as ChannelConfig;

        if (taskConfig is null || channelConfig is null)
        {
            _logger.LogError("{dateTimeUtc}: {JobId} TaskConfig or ChannelConfig is null",
                dateTimeUtc, JobId);
            return;
        }

        // 根据 TaskConfig 执行任务逻辑
        _logger.LogInformation("{dateTimeUtc}: {JobId} Executing task: {taskConfigName}", dateTimeUtc, JobId,
            taskConfig.Name);

        float[] rawData;
        float coef = 0f;
        int freq = 0;

        if (channelConfig.DataSrcType == DataSrcType.JianLong)
        {
            // 获取 VibDataEnumerator
            var vibDataEnumerator = context.MergedJobDataMap.Get("VibDataEnumerator") as VibDataEnumerator;
            if (vibDataEnumerator is null)
            {
                _logger.LogError("{dateTimeUtc}: {JobId} VibDataEnumerator is null", dateTimeUtc, JobId);
                return;
            }
            
            // 从 VibDataEnumerator 获取数据
            (_, rawData, coef, freq) = vibDataEnumerator.GetNextData(channelConfig.Dir);
        }
        else if (channelConfig.DataSrcType == DataSrcType.WeiLi)
        {
            // 获取 WeiLiVibDataEnumerator
            var weiLiVibDataEnumerator = context.MergedJobDataMap.Get("WeiLiVibDataEnumerator") as WeiLiVibDataEnumerator;
            if (weiLiVibDataEnumerator is null)
            {
                _logger.LogError("{dateTimeUtc}: {JobId} WeiLiVibDataEnumerator is null", dateTimeUtc, JobId);
                return;
            }
            
            // 从 WeiLiVibDataEnumerator 获取数据
            (_, rawData, coef, freq) = weiLiVibDataEnumerator.GetNextData();
        }
        else
        {
            _logger.LogError("{dateTimeUtc}: {JobId} Unsupported DataSrcType: {DataSrcType}",
                dateTimeUtc, JobId, channelConfig.DataSrcType);

            return;
        }

        byte[] rawBinData = GenerateVibBinData(rawData, coef);
        uint crc = rawBinData.GetCrc32();

        string topic = channelConfig.Topic;

        WaveDataModel waveData = new WaveDataModel
        {
            Id = new Random().Next(10000, 100000),
            PackCount = 1,
            PackIndex = 0,
            ChNo = channelConfig.ChNo,
            // 暂时没有 ChType
            // ChType = channelConfig.ChType,
            Dir = channelConfig.Dir,
            Code = channelConfig.Code,
            Time = dateTimeUtc.ToString("yyyy-MM-ddTHH:mm:ss"),
            PlusLength = 0,
            Freq = freq,
            RPM = 0,
            TimeMark = 0,
            Coef = coef,
            Src = 0,
            IsSensor = 1,
            Content = rawBinData,
            CRC = crc,
            // AlarmLevel = alarmLevelCandidateArray[new Random().Next(0, 14)],
        };

        int? alarmLevel = GetAlarmLevel(taskConfig.AlarmLevel);
        
        if (alarmLevel is not null)
        {
            waveData.AlarmLevel = alarmLevel.Value;
        }

        // 配置 JsonSerializerOptions 忽略 null 值
        var options = new JsonSerializerOptions
        {
            DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
        };

        using (var mqttClientWrapper = await _mqttClientPool.GetClientAsync())
        {
            var message = new MqttApplicationMessageBuilder()
                .WithTopic(topic)
                .WithPayload(System.Text.Json.JsonSerializer.Serialize(waveData, options))
                .WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtMostOnce)
                .Build();

            if (mqttClientWrapper.Client.IsStarted && mqttClientWrapper.Client.IsConnected)
            {
                await mqttClientWrapper.Client.EnqueueAsync(message);
            }
            else
            {
                _logger.LogError("{dateTimeUtc}: {JobId} MQTT client is not started or connected", dateTimeUtc, JobId);
            }
        }
    }

    private static byte[] GenerateVibBinData(float[] data, float coef)
    {
        List<byte> byteList = [];

        foreach (float value in data)
        {
            // 将浮点数除以系数并转换为 16 位整数
            short intValue = (short)(value / coef);

            // 将 16 位整数转换为字节数组
            byte[] bytes = BitConverter.GetBytes(intValue);

            // 如果系统是小端序，需要调整为大端序
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(bytes);
            }

            // 将字节添加到列表
            byteList.AddRange(bytes);
        }

        // 将字节列表转换为字节数组
        byte[] byteArray = byteList.ToArray();
        return byteArray;
    }

    private static int? GetAlarmLevel(AlarmLevel alarmLevel)
    {
        return alarmLevel switch
        {
            AlarmLevel.None => null,
            AlarmLevel.C => 3,
            AlarmLevel.D => 4,
            _ => null
        };
    }
}